本篇內容參考連結
原型基礎物件導向
Roya's Blog
ZWE ZONE
上一篇了解到, call by value, reference 和 sharing 的區別後, 就可以開始探討甚麼是淺拷貝(shallow copy)和深拷貝. 還有為何會需要有這兩種不同的拷貝.
當我們再進行"複製"的動作時, 分為淺拷貝跟深拷貝
所以當我們想要複製物件, 並使其不互相影響, 就會需要做深拷貝的動作了.
直接來參考範例
var originalObject = { a: "1", b: "2", c: "3" };
var originalArray = ["1", "2", "3"];
var orignialObjectInObject = { a: { content: "original" }, b: "2", c: "3" };
var copyObject = Object.assign({}, originalObject);
copyObject.a = "changed";
var copyArray = Object.assign([], originalArray);
copyArray[0] = "changed";
var copyObjectInObject = Object.assign({}, orignialObjectInObject);
copyObjectInObject.a.content = "updated";
console.log(originalObject); // { a: "1", b: "2", c: "3" } -> 原物件不受影響
console.log(copyObject); // { a: "changed", b: "2", c: "3" }
console.log(originalArray); // ["1", "2", "3"] -> 原物件不受影響
console.log(copyArray); // ["changed", "2", "3"]
console.log(orignialObjectInObject); // { a: { content: 'updated' }, b: '2', c: '3' } -> 原物件受影響
console.log(copyObjectInObject); // { a: { content: 'updated' }, b: '2', c: '3' }
乍看之下Object.assign()好像是deep clone, 事實上, Object.assign()僅是複製屬性值, 若來源物件值也是一個物件(Object), 則只會複製其子物件的reference.
使用 ES6 語法的 { … obj } 或是 Object.assign({}, obj) 都是不錯的淺拷貝方式. 效能也相對比較好
比較熟悉的應該就是 JSON.parse(JSON.stringify(obj)). 但效能相對比較不好.
var originalObject = { text: "Hello" };
var copyObject;
copyObject = JSON.parse(JSON.stringify(originalObject));
copyObject.text = "Hi";
console.log(originalObject); // { text: 'Hello' }
console.log(copyObject); // { text: 'Hi' }
其他像是常見的 lodash 資料庫的 cloneDeep方法, 效能稍微好一點. 或是利用遞迴來每一個賦予值.